import Animations from '../modules/Animations'
import Fill from '../modules/Fill'
import Filters from '../modules/Filters'
import Graphics from '../modules/Graphics'
import Markers from '../modules/Markers'

/**
 * ApexCharts Scatter Class.
 * This Class also handles bubbles chart as currently there is no major difference in drawing them,
 * @module Scatter
 **/
class Scatter {
  constructor (ctx) {
    this.ctx = ctx
    this.w = ctx.w

    this.initialAnim = this.w.config.chart.animations.enabled
    this.dynamicAnim = this.initialAnim && this.w.config.chart.animations.dynamicAnimation.enabled

    // this array will help in centering the label in bubbles
    this.radiusSizes = []
  }

  draw (elSeries, j, opts) {
    let w = this.w

    let anim = new Animations(this.ctx)
    let graphics = new Graphics(this.ctx)
    let filters = new Filters(this.ctx)
    let fill = new Fill(this.ctx)

    let realIndex = opts.realIndex
    let pointsPos = opts.pointsPos
    let zRatio = opts.zRatio
    let elPointsMain = opts.elParent

    let pathFillCircle = fill.fillPath(elSeries, {
      seriesNumber: realIndex
    })

    let elPointsWrap = graphics.group({
      class: `apexcharts-series-markers apexcharts-series-${w.config.chart.type}`
    })

    if (pointsPos.x instanceof Array) {
      for (let q = 0; q < pointsPos.x.length; q++) {
        let realIndexP = j + 1

        // a small hack as we have 2 points for the first val to connect it
        if (j === 0 && q === 0) realIndexP = 0
        if (j === 0 && q === 1) realIndexP = 1

        let radius = 0
        let finishRadius = w.config.markers.size

        if (zRatio !== Infinity) {
          // means we have a bubble
          finishRadius = w.globals.seriesZ[realIndex][realIndexP] / zRatio
          if (typeof this.radiusSizes[realIndex] === 'undefined') {
            this.radiusSizes.push([])
          }
          this.radiusSizes[realIndex].push(finishRadius)
        }

        if (!w.config.chart.animations.enabled) {
          radius = finishRadius
        }

        let x = pointsPos.x[q]
        let y = pointsPos.y[q]

        x = x || 0
        y = y || 0
        radius = radius || 0

        if ((x === 0 && y === 0) || typeof w.globals.series[realIndex][realIndexP] === 'undefined') return

        let circle = graphics.drawCircle(radius)

        circle.attr({
          cx: x,
          cy: y,
          fill: pathFillCircle
        })

        if (w.config.chart.dropShadow.enabled) {
          filters.dropShadow(circle, {
            top: w.config.chart.dropShadow.top,
            left: w.config.chart.dropShadow.left,
            blur: w.config.chart.dropShadow.blur
          })
        }

        if (this.initialAnim && !w.globals.dataChanged) {
          let speed = 1
          if (!w.globals.resized) {
            speed = w.config.chart.animations.speed
          }
          anim.animateCircleRadius(circle, 0, finishRadius, speed)
        }

        if (w.globals.dataChanged) {
          if (this.dynamicAnim) {
            let speed = w.config.chart.animations.dynamicAnimation.speed
            let prevX, prevY, prevR

            let prevPathJ = w.globals.previousPaths[realIndex][j]

            if (typeof prevPathJ !== 'undefined') {
            // series containing less elements will ignore these values and revert to 0
              prevX = prevPathJ.x
              prevY = prevPathJ.y
              prevR = typeof prevPathJ.r !== 'undefined'
                ? prevPathJ.r
                : finishRadius
            }

            for (let cs = 0; cs < w.globals.collapsedSeries.length; cs++) {
              if (w.globals.collapsedSeries[cs].index === realIndex) {
                speed = 1
                finishRadius = 0
              }
            }

            if (x === 0 && y === 0) finishRadius = 0

            // if (!w.globals.risingSeries.includes(realIndex)) {
            //   anim.animateCircle(circle, {
            //     cx: prevX, cy: prevY, r: prevR
            //   }, {
            //     cx: x, cy: y, r: finishRadius
            //   }, speed)
            // }
            // else {
            anim.animateCircle(circle, {
              cx: prevX, cy: prevY, r: prevR
            }, {
              cx: x, cy: y, r: finishRadius
            }, speed)
            // }
          } else {
            circle.attr({
              r: finishRadius
            })
          }
        }

        circle.attr({
          'rel': realIndexP,
          'j': realIndexP,
          'index': realIndex
        })

        const markers = new Markers(this.ctx)
        markers.setSelectedPointFilter(circle, realIndex, realIndexP)
        markers.addEvents(circle)

        circle.node.classList.add('apexcharts-marker')

        elPointsWrap.add(circle)

        elPointsMain.add(elPointsWrap)
      }
    }
  }

  centerTextInBubble (y, i, realIndexP) {
    let w = this.w
    y = y + (parseInt(w.config.dataLabels.style.fontSize) / 4)

    return {
      y
    }
  }
}

module.exports = Scatter
